package com.shenzw.mybatisdemo.controller;

import com.shenzw.mybatisdemo.aop.ResponseResult;
import com.shenzw.mybatisdemo.controller.param.BaseGroup;
import com.shenzw.mybatisdemo.controller.request.UserRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 在使用 spring开发过程中，我们经常回进行参数校验，严格的参数校验可以避免系统出现 bug 和 安全漏洞，参数校验主要使用依赖
 * <dependency>
 * <groupId>org.hibernate.validator</groupId>
 * <artifactId>hibernate-validator</artifactId>
 * <version>8.0.0.Final</version>
 * </dependency>
 * <p>
 * 也可以使用 spring-boot-starter-validation
 * <dependency>
 * <groupId>org.springframework.boot</groupId>
 * <artifactId>spring-boot-starter-validation</artifactId>
 * <version>3.1.0</version>
 * </dependency>
 * <p>
 * 使用注解进行参数校验，可以避免在 controller层 或者 service层编写大量的 if else 代码，使代码更加简洁易读
 * 今天分享的三个场景案例：
 * 1. 使用 hibernate.validator 内置注解进行常规参数校验，数据分组校验；
 * 2. 通过自定义注解，实现参数传参数值是否符合规定校验；
 * 3. 通过自定义注解 + ControllerAdvice + RequestBodyAdvice 实现对请求参数的转换；
 *
 * @author shenzw
 * @date 2023/12/7
 */
@RestController
@RequestMapping("/validator")
@Slf4j
@ResponseResult
public class ValidatorController {

    @PostMapping("/addUser")
    public UserRequest addUser(@Valid @RequestBody UserRequest user) {
        user.checkIdCardAndRealName();
        log.info("UserRequest = {}", user);
        return user;
    }

    @PostMapping("/updateUser")
    public UserRequest updateUser(@Validated({BaseGroup.Update.class, BaseGroup.Insert.class}) @RequestBody UserRequest user) {
        user.checkIdCardAndRealName();
        log.info("UserRequest = {}", user);
        return user;
    }

    public static void main(String[] args) {
        Matcher matcher = Pattern.compile("1[3-9]\\d{9}").matcher("18273735069");
        System.out.println(matcher.matches()); // true

    }
}
